package com.myworkspace.standard.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.myworkspace.standard.common.utils.CustomUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * json转换工具类 jackson
 *
 */
public class JackSonJsonConvert {

    private static ObjectMapper instence = null;

    /**
     * 初始化
     */
    public static void initMapper() {
        if (instence != null) {
        } else {
            instence = new ObjectMapper();
            instence.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            instence.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            //将BigDecimal,Long类型转换为String
            SimpleModule simpleModule = new SimpleModule();
            simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
            simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
            simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
            instence.registerModule(simpleModule);
        }
    }

    /**
     * 把Json串转换为 map
     *
     * @param json
     * @return
     * @throws IOException
     */
    public static Map<String, Object> jsonStrToMap(String json) throws IOException {
        initMapper();
        Map<String, Object> map;
        try {
            map = instence.readValue(json, HashMap.class);
        } catch (Exception ex) {
            map = instence.readValue(json.replace("\\", ""), HashMap.class);
        }
        return map;
    }

    /**
     * 把json串转换为对应的Javabean对象
     *
     * @param json json串
     * @param cls  javabean cls
     * @return
     * @throws IOException
     */
    public static <T> T jsonStrToObject(String json, Class<T> cls) throws IOException {
        initMapper();
        T returnObj;
        try {
            returnObj = instence.readValue(json, cls);
        } catch (Exception ex) {
            returnObj = instence.readValue(json.replace("\\", ""), cls);
        }
        return returnObj;
    }

    /**
     * 把json串转换为对应的Javabean对象集合
     *
     * @param json json串
     * @param cls  javabean cls
     * @return
     * @throws IOException
     */
    public static <T> List<T> jsonStrToList(String json, Class<T> cls) throws IOException {
        initMapper();
        List<T> returnObj;
        try {
            returnObj = instence.readValue(json, getCollectionType(instence, ArrayList.class, cls));
        } catch (Exception ex) {
            returnObj = instence.readValue(json.replace("\\", ""), getCollectionType(instence, ArrayList.class, cls));
        }
        return returnObj;
    }

    /**
     * 将实体转换为JSON字符串
     *
     * @param obj
     * @return
     * @throws JsonProcessingException
     */
    public static String objectTojsonStr(Object obj) throws JsonProcessingException {
        initMapper();
        return instence.writeValueAsString(obj);
    }

    /**
     * 获取泛型的Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(ObjectMapper mapper, Class<?> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }


    /**
     * listmap转jsonarray字符串 key都以字符串显示
     *
     * @param list
     * @return
     */
    public static JSONArray convertListMapToListJsonObj(List<Map<String, Object>> list) {
        JSONArray objectList = new JSONArray();
        if (list != null && !list.isEmpty()) {
            for (Map<String, Object> map : list) {
                Iterator iterator = map.entrySet().iterator();
                JSONObject obj = new JSONObject();
                while (iterator.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    if (entry.getKey().toString().toUpperCase().contains("ID")) {
                        obj.put(entry.getKey().toString(), CustomUtils.Nvl(entry.getValue(), ""));
                    } else {
                        obj.put(entry.getKey().toString(), entry.getValue());
                    }
                }
                objectList.add(obj);
            }
        }
        return objectList;
    }

    /**
     * map转jsonObject字符串 key都以字符串显示
     *
     * @param map
     * @return
     */
    public static JSONObject convertMapToJsonObj(Map<String, Object> map) {
        Iterator iterator = map.entrySet().iterator();
        JSONObject obj = new JSONObject();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (entry.getKey().toString().contains("id")) {
                obj.put(entry.getKey().toString(), CustomUtils.Nvl(entry.getValue(), ""));
            } else {
                obj.put(entry.getKey().toString(), entry.getValue());
            }
        }
        return obj;
    }

    /**
     * StringMap转jsonObject字符串 key都以字符串显示
     *
     * @param map
     * @return
     */
    public static JSONObject convertStringMapToJsonObj(Map<String, String> map) {
        Iterator iterator = map.entrySet().iterator();
        JSONObject obj = new JSONObject();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (entry.getKey().toString().contains("id")) {
                obj.put(entry.getKey().toString(), CustomUtils.Nvl(entry.getValue(), ""));
            } else {
                obj.put(entry.getKey().toString(), entry.getValue());
            }
        }
        return obj;
    }

    /**
     * test测试
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws Exception {
       /* JSONObject object = new JSONObject();
        object.put("app", "ios");
        object.put("appVersion", "1.5.7");
        object.put("channel", "index");
        object.put("id", "1");
        object.put("fromId", "");
        object.put("page", "index");
        object.put("pageFullUrl", "index");
        object.put("action", "alert");//alert 活动弹层 // downLoad 立即下载  float 悬浮窗入口  invitedBtn 去邀请  share
        object.put("eventId", "activityId");
        object.put("eventIndex", "");
        object.put("eventTime", "");//当前时间时间戳
        object.put("userId", "用户id");
        String str = JackSonJsonConvert.objectTojsonStr(object);
        Activity_PointLogModel callBack_pointLogModel = JackSonJsonConvert.jsonStrToObject(str, Activity_PointLogModel.class);
        System.out.println(JackSonJsonConvert.objectTojsonStr(callBack_pointLogModel));

        System.out.println(URLDecoder.decode("https://wx8a2e52b95b1f558a.m-dev.meiyintutu.com/home.html?&param=%7B%22backType%22%3A%22scan%22%7D&appId=wx8a2e52b95b1f558a", "utf-8"));

        Random r = new Random(1);
        for (int i = 0; i < 100; i++) {
            int ran1 = r.nextInt(30);
            System.out.println(ran1 / 10);
        }*/
//        System.out.println(new String(MY_Base64.decode("YWxidW1fNTQ0MjIwNzMwMzI2NDI5Njk2")));
    }


    /**
     * 将http请求协议的图片地址替换为https
     *
     * @param object
     * @return
     */
    public static String convertHttpToHttps(Object object) {
        String newStr = null;
        if (object != null) {
            newStr = object.toString();
            List<Map<String, String>> replaceList = new ArrayList<>();
            replaceList = JackSonJsonConvert.findAllHttpStr(newStr, replaceList);
            if (replaceList != null && replaceList.size() > 0) {
                Iterator<Map<String, String>> iterator = replaceList.iterator();
                while (iterator.hasNext()) {
                    Map<String, String> map = iterator.next();
                    newStr = newStr.replace(map.get("replaceFrom"), map.get("replaceTo"));
                }
            }
        }
        return newStr;
    }

    /**
     * 将json字符串中的所有图片链接为http请求协议的替换为https协议 并返回list集合
     * 实现；将json字符串转为数组 如果失败则转为对象 如果失败则说明为字符串
     * 这时将值中包含有http的请求协议更换为https协议 并保存
     *
     * @param value
     * @param list
     * @return
     */
    private static List<Map<String, String>> findAllHttpStr(Object value, List<Map<String, String>> list) {
        if (value != null) {
            String valueStr = value.toString();
            try {
                com.alibaba.fastjson.JSONArray jsonArray = com.alibaba.fastjson.JSONArray.parseArray(valueStr);
                Iterator iterator = jsonArray.iterator();
                while (iterator.hasNext()) {
                    Object object = iterator.next();
                    findAllHttpStr(object, list);
                }
            } catch (Exception e) {
                try {
                    com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(valueStr);
                    Collection collection = jsonObject.values();
                    Iterator iterator = collection.iterator();
                    while (iterator.hasNext()) {
                        Object obj = iterator.next();
                        findAllHttpStr(obj, list);
                    }
                } catch (Exception e1) {
                    if (CustomUtils.isImage(valueStr.toString())) {
                        Map<String, String> map = new HashMap<>();
                        map.put("replaceFrom", valueStr);
                        valueStr = value.toString().replace("http://", "https://");
                        map.put("replaceTo", valueStr);
                        list.add(map);
                    }
                }
            }
        }
        return list;
    }
}
